/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-02-20
*/
package com.rzico.order.controller.admin;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rzico.annotation.Log;
import com.rzico.base.BaseController;
import com.rzico.base.CommResult;
import com.rzico.basics.entity.*;
import com.rzico.basics.service.*;
import com.rzico.core.entity.SysEmployee;
import com.rzico.core.entity.SysOffice;
import com.rzico.core.entity.SysReport;
import com.rzico.core.entity.SysUser;
import com.rzico.core.service.*;
import com.rzico.entity.PageResult;
import com.rzico.entity.Pageable;
import com.rzico.exception.CustomException;
import com.rzico.order.entity.Warehouse;
import com.rzico.order.enumx.WarehouseTypeEnum;
import com.rzico.order.service.WarehouseItemService;
import com.rzico.order.service.WarehouseService;
import com.rzico.util.HttpUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.jasperreports.engine.JRException;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 出入库单控制层
 *
 * @author Rzico Boot
 * @version 1.0
 * @date 2020-02-20
 */
@Api(description = "出入库单接口")
@RestController
@RequestMapping("/admin/warehouse")
public class WarehouseAdminController extends BaseController {

    @Value("${rzico.filePath.windows}")
    private String windowsFilePath;

    @Value("${rzico.filePath.linux}")
    private String linuxFilePath;

    @Autowired
    private WarehouseService warehouseService;
    @Autowired
    private WarehouseItemService warehouseItemService;

    @Autowired
    private SysOfficeService sysOfficeService;

    @Autowired
    protected SysEmployeeService sysEmployeeService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private SupplierService supplierService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private ProductService productService;

    @Autowired
    private SysReportService sysReportService;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    protected SysUserService sysUserService;

    @Autowired
    private SysUserDataScopeService sysUserDataScopeService;


    /**
     * 分页查询出入库单
     *
     * @return
    */
    @ApiOperation("分页查询出入库单")
    @GetMapping("/list")
    @ApiImplicitParams({@ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "String", paramType = "query") ,
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "单据状态(0.未确认,1.已确认,2.已完成,3.已取消)", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "warehouseType", value = "单据类型(1.采购入库,2.采购退货,3.调拨入库,4.销售出库,5.销售退货,6.调拨出库,7.盘点损益,8.其他出库)", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "sn", value = "单据编号", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "companyId", value = "所属企业", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "productId", value = "商品ID", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "orderSn", value = "订单编号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "supplierId", value = "供应商", dataType = "Long", paramType = "query")
    })
    public CommResult<Warehouse> list(Date startDate, Date endDate, Long companyId, Integer status,
                                      Integer warehouseType, Long sn, String orderSn, Long supplierId,
                                      Long productId, Pageable pageable) {
        Map<String, Object> params = new HashMap<String, Object>();
        params = buildSortField(params, pageable);
        if (startDate!=null){
            params.put("startDate", DateUtils.truncate(startDate, Calendar.DATE));
        }
        if (endDate!=null){
            params.put("endDate", DateUtils.addMilliseconds(DateUtils.addDays(endDate,1),-1));
        }
        if (null != supplierId){
            params.put("supplierId", supplierId);
        }
        if (null != companyId){
            params.put("companyId", companyId);
        }
        if (null != status){
            params.put("status", status);
        }
        if (null != warehouseType){
            params.put("warehouseType", warehouseType);
        }
        if (null != sn){
            params.put("sn", sn);
        }
        if (null != orderSn){
            params.put("orderSn", orderSn);
        }
        if (null != productId){
            Product product = productService.findById(productId);
            params.put("goodsId", product.getGoodsId());
        }
        params.put("deleted", false);


        Enterprise enterprise = enterpriseService.getCurrent();
        if (enterprise!=null) {
            params.put("enterpriseId", enterprise.getId());
        } else {
            return CommResult.error("没有开通企业");
        }

        //非管理员都启用数据权限
        SysUser sysUser = sysUserService.getCurrent();
        if (!sysUserService.isAdmin(sysUser)) {
            //params.put("dataScopeId",sysUser.getId());
            if (sysUserDataScopeService.checkHasPermissio(sysUser.getId(),2)) {
                if (sysUser.getMchId().equals(enterprise.getMchId())) {
                    params.put("shopScopeId", sysUser.getId());
                }
            } else {
                params.put("createBy",sysUser.getId());
            }
        }


        Page<Object> startPage = PageHelper.startPage(pageable.getPageNum(), pageable.getPageSize());
        List<Warehouse> list = warehouseService.selectList(params);
        PageResult<Warehouse> pageResult = new PageResult<Warehouse>(list, startPage.getTotal(), pageable);
        return CommResult.success(pageResult);
    }

    /**
     * 查询单条出入库单
     *
     * @return
    */
    @ApiOperation("查询单条出入库单")
    @GetMapping("/find/{id}")
    public CommResult<Warehouse> find(@PathVariable String id) {
        Warehouse result = warehouseService.findById(id);
        if (null == result){
            throw new CustomException("尚未查找到单据");
        }
        Map<String,Object> data = new HashMap<>();
        data.put("warehouse",result);


        Map<String,Object> params = new HashMap<>();
        params.put("warehouseId",result.getId());
        result.setItemList(warehouseItemService.selectList(params));

        if (result.getOfficeId()!=null) {
            SysOffice sysOffice = sysOfficeService.selectByPrimaryKey(result.getOfficeId());
            if (sysOffice!=null) {
                data.put("officeName", sysOffice.getName());
            }
        } else {
            data.put("officeName", "无");
        }
        if (result.getOperatorId()!=null) {
            SysEmployee sysUser = sysEmployeeService.selectByPrimaryKey(result.getOperatorId());
            if (sysUser!=null) {
                data.put("operatorName", sysUser.getName());
            } else {
                data.put("operatorName", "无");
            }
        } else {
            data.put("operatorName", "无");
        }
        if (result.getMemberId()!=null) {
            Member member = memberService.selectByPrimaryKey(result.getMemberId());
            if (member!=null) {
                data.put("memberName", member.getName());
            }
        }
        if (result.getSupplierId()!=null) {
            Supplier supplier = supplierService.selectByPrimaryKey(result.getSupplierId());
            if (supplier!=null) {
                data.put("supplierName", supplier.getName());
            }
        }

        if (result.getShopId()!=null) {
            Shop shop = shopService.selectByPrimaryKey(result.getShopId());
            if (shop!=null) {
                data.put("shopName", shop.getName());
            }
        } else {
            data.put("shopName", "无");
        }

        return CommResult.success(data);

    }

    /**
     * 保存出入库单
     *
     * @param warehouse
     * @return
     */
    @ApiOperation("保存出入库单")
    @PostMapping("/save")
    public CommResult<Warehouse> save(@RequestBody Warehouse warehouse) {
        Assert.notNull(warehouse.getOrderId(), "来源单号不能为空");
        Assert.notNull(warehouse.getWarehouseType(), "出入库类型为空");
        Assert.notNull(warehouse.getShopId(), "仓库为空");
        Assert.notNull(warehouse.getItemList(), "单据明细为空");
        Assert.notNull(warehouse.getSubPrice(), "商品金额合计为空");
        Assert.notNull(warehouse.getSubQuantity(), "数量合计为空");

        Enterprise enterprise = enterpriseService.getCurrent();
        warehouse.setEnterpriseId(enterprise.getId());

        SysUser sysUser = sysUserService.getCurrent();
        if (sysUser!=null) {
            warehouse.setCreateBy(sysUser.getId());
        }

        if (warehouse.getMemberId()!=null) {
            Member member = memberService.selectByPrimaryKey(warehouse.getMemberId());
            if (member!=null) {
                warehouse.setCompanyId(member.getCompanyId());
            }
        }

        if (warehouse.getOrderMethod()==null) {
            warehouse.setOrderMethod(1);
        }

        int affectCount = warehouseService.insertWarehouse(warehouse);
        if (affectCount <= 0) {
            return CommResult.error();
        }
        Warehouse result = warehouseService.findById(warehouse.getId());
        return CommResult.success(result);

    }


    /**
     * 保存并出库
     *
     * @param warehouse
     * @return
     */
    @ApiOperation("保存并确认")
    @PostMapping("/saveAndConfirm")
    public CommResult<Warehouse> saveAndConfirm(@RequestBody Warehouse warehouse) {
        Assert.notNull(warehouse.getOrderId(), "来源单号不能为空");
        Assert.notNull(warehouse.getWarehouseType(), "出入库类型为空");
        Assert.notNull(warehouse.getShopId(), "仓库为空");
        Assert.notNull(warehouse.getItemList(), "单据明细为空");
        Assert.notNull(warehouse.getSubPrice(), "商品金额合计为空");
        Assert.notNull(warehouse.getSubQuantity(), "数量合计为空");

        Enterprise enterprise = enterpriseService.getCurrent();
        warehouse.setEnterpriseId(enterprise.getId());

        SysUser sysUser = sysUserService.getCurrent();
        if (sysUser!=null) {
            warehouse.setCreateBy(sysUser.getId());
        }

        if (warehouse.getMemberId()!=null) {
            Member member = memberService.selectByPrimaryKey(warehouse.getMemberId());
            if (member!=null) {
                warehouse.setCompanyId(member.getCompanyId());
            }
        }

        if (warehouse.getOrderMethod()==null) {
            warehouse.setOrderMethod(1);
        }

        int affectCount = warehouseService.saveAndConfirm(warehouse);
        if (affectCount <= 0) {
            return CommResult.error();
        }
        Warehouse result = warehouseService.findById(warehouse.getId());
        return CommResult.success(result);

    }


    /**
     * 保存并出库
     *
     * @param warehouse
     * @return
     */
    @ApiOperation("保存并出库")
    @PostMapping("/saveAndOutStock")
    public CommResult<Warehouse> saveAndOutStock(@RequestBody Warehouse warehouse) {
        Assert.notNull(warehouse.getOrderId(), "来源单号不能为空");
        Assert.notNull(warehouse.getWarehouseType(), "出入库类型为空");
        Assert.notNull(warehouse.getShopId(), "仓库为空");
        Assert.notNull(warehouse.getItemList(), "单据明细为空");
        Assert.notNull(warehouse.getSubPrice(), "商品金额合计为空");
        Assert.notNull(warehouse.getSubQuantity(), "数量合计为空");

        Enterprise enterprise = enterpriseService.getCurrent();
        warehouse.setEnterpriseId(enterprise.getId());

        SysUser sysUser = sysUserService.getCurrent();
        if (sysUser!=null) {
            warehouse.setCreateBy(sysUser.getId());
        }

        if (warehouse.getMemberId()!=null) {
            Member member = memberService.selectByPrimaryKey(warehouse.getMemberId());
            if (member!=null) {
                warehouse.setCompanyId(member.getCompanyId());
            }
        }

        if (warehouse.getOrderMethod()==null) {
            warehouse.setOrderMethod(1);
        }

        int affectCount = warehouseService.saveAndOutStock(warehouse);
        if (affectCount <= 0) {
            return CommResult.error();
        }
        Warehouse result = warehouseService.findById(warehouse.getId());
        return CommResult.success(result);

    }

    /**
     * 批量删除出入库单
     *
     * @param ids
     * @return
     */
    @Log(desc = "批量删除出入库单", type = Log.LOG_TYPE.DEL)
    @ApiOperation("批量删除出入库单,ids用逗号拼接")
    @PostMapping("/del/{ids}")
    public CommResult<Warehouse> del(@PathVariable String ids) {

        try {
            warehouseService.deleteByIds(ids.split(","));
        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }

        return CommResult.success();
    }

    /**
     * 修改出入库单
     *
     * @param warehouse
     * @return
     */
    @ApiOperation("修改出入库单")
    @PostMapping("/update")
    public CommResult<Warehouse> updateWarehouse(@RequestBody Warehouse warehouse) {
        Assert.notNull(warehouse.getOrderId(), "来源单号不能为空");
        Assert.notNull(warehouse.getId(), "单号为空");
        Assert.notNull(warehouse.getItemList(), "单据明细为空");

        if (warehouse.getMemberId()!=null) {
            Member member = memberService.selectByPrimaryKey(warehouse.getMemberId());
            if (member!=null) {
                warehouse.setCompanyId(member.getCompanyId());
            }
        }


        int affectCount = warehouseService.updateWarehouse(warehouse);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Warehouse result = warehouseService.findById(warehouse.getId());
        return CommResult.success(result);
    }


    /**
     * 确认出入库单
     * 回写各种单据的发货、退货数量
     *
     * @param id
     * @return
     */
    @ApiOperation("确认出入库单")
    @PostMapping("/confirm/{id}")
    public CommResult<Warehouse> confirm(@PathVariable Long id) {
        try {
            warehouseService.confirm(id);
        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }
        Warehouse result = warehouseService.findById(id);
        return CommResult.success(result);
    }

    /**
     * 审核出入库单
     *
     * @param id
     * @return
     */
    @ApiOperation("审核出入库单")
    @PostMapping("/audit/{id}")
    @ApiImplicitParams({@ApiImplicitParam(name = "result", value = "审核结果(0驳回 1通过)", dataType = "Integer", paramType = "query") })
    public CommResult<Warehouse> audit(@PathVariable Long id) {
        int affectCount = warehouseService.audit(id);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Warehouse warehouse = warehouseService.findById(id);
        return CommResult.success(warehouse);
    }


    /**
     * 弃审出入库单(弃审已完成的出入库)
     * @param id
     * @return
     */
    @ApiOperation("弃审出入库单")
    @PostMapping("/disAudit/{id}")
    public CommResult<Warehouse> disAudit(@PathVariable Long id) {
        int affectCount = warehouseService.disAudit(id);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Warehouse result = warehouseService.findById(id);
        return CommResult.success(result);
    }


    /**
     * 作废(已确认、未确认可以作废)
     * @param id
     * @return
     */
    @ApiOperation("作废")
    @PostMapping("/cancel/{id}")
    public CommResult<Warehouse> cancel(@PathVariable Long id) {
        int affectCount = warehouseService.cancel(id);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Warehouse result = warehouseService.findById(id);
        return CommResult.success(result);
    }

    /**
     *  订单打印
     *
     * @param id
     * @return
     */
    @ApiOperation("打印")
    @GetMapping("/print/{id}")
    public void print(HttpServletRequest request, HttpServletResponse response, @PathVariable String id)
            throws ClassNotFoundException, SQLException, JRException, IOException, IllegalAccessException{
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>订单打印 start<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        Map<String, Object> param = new HashMap<String, Object>();
        param = HttpUtils.requestParam(request);

        Warehouse order = warehouseService.selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("订单不存在");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Enterprise enterprise = enterpriseService.selectByPrimaryKey(order.getEnterpriseId());
        if (null == enterprise) {
            throw new CustomException("没有开通企业");
        }
        SysOffice sysOffice = sysOfficeService.findById(order.getOfficeId());
        if (null != sysOffice){
            param.put("officeName",sysOffice.getOfficeName());
        }
        param.put("COMPANY",enterprise.getName());
        param.put("enterpriseId",enterprise.getId());

        param.put("consignee", order.getConsignee());
        param.put("address", order.getAddress());
        param.put("phone", order.getPhone());
        param.put("orderDate", sdf.format(order.getOrderDate()));
        param.put("memo", order.getMemo());
        param.put("sn", order.getSn());

        param.put("inShopName", order.getConsignee());
        param.put("outShopName", order.getAddress());
        String memberName = "";
        if (order.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_OUT.getId()) ||
                order.getWarehouseType().equals(WarehouseTypeEnum.WAREHOUSE_TYPE_SALE_IN.getId())){
            Member member = memberService.selectByPrimaryKey(order.getMemberId());
            if (null != member){
                memberName = member.getName();
            }
        }else{
            Supplier supplier = supplierService.selectByPrimaryKey(order.getSupplierId());
            if (null != supplier){
                memberName = supplier.getName();
            }
        }
        param.put("memberName", memberName);

        logger.info("打印报表查询参数：{}", param.toString());

        String fileName = enterprise.getMchId()+"_"+order.getSn() + ".jasper";
        //fileName就是sys_report表的id
        SysReport sysReport = sysReportService.selectByPrimaryKey(fileName);

        String filePath = "";
        if (System.getProperty("os.name").contains("Windows")) {
            filePath = windowsFilePath;
        } else if (System.getProperty("os.name").contains("Linux")) {
            filePath = linuxFilePath;
        }
        //检查服务器上是否存在模板
        File file = new File(filePath + File.separator + fileName);
        if (!file.exists()){
            try {
                String url = sysReport == null?"":sysReport.getTemplate();
                sysReportService.fileDownLoad(response, url, filePath, fileName);
            } catch (Exception e){
                logger.info("打印模板下载失败");
                throw new CustomException("打印模板下载失败");
            }
        }

        String typeName = WarehouseTypeEnum.getNameById(order.getWarehouseType());
        param.put("REPORT_NAME",typeName);

        String reportName = getName(order.getWarehouseType());
        StringBuffer sql = new StringBuffer();
        sql.append(" SELECT b.sn,b.name,b.spec,b.cost,b.unit, ");
        sql.append("    b.price,b.quantity,round(b.price*b.quantity, 2) as amount,b.discount FROM wx_warehouse_item b ");
        sql.append(" WHERE b.warehouse_id = "+id);

        File file2 = new File(filePath + File.separator + fileName);
        if (!file2.exists()) {
            //下载之后还不存在，就使用classpath路径的模板
            sysReportService.ReportToPdfBySql(reportName, param, sql.toString(), response);
        }else{
            sysReportService.commReportToPdf(filePath, fileName, param, sql.toString(), response);
        }
    }


    /**
     *  订单打印
     *
     * @param id
     * @return
     */
    @ApiOperation("导出")
    @GetMapping("/export/{id}")
    public void export(HttpServletRequest request, HttpServletResponse response, @PathVariable String id)
            throws ClassNotFoundException, SQLException, JRException, IOException, IllegalAccessException{
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>订单打印 start<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        Map<String, Object> param = new HashMap<String, Object>();
        Warehouse order = warehouseService.selectByPrimaryKey(id);
        if (null == order){
            throw new CustomException("订单不存在");
        }

        Enterprise enterprise = enterpriseService.selectByPrimaryKey(order.getEnterpriseId());
        param.put("COMPANY",enterprise.getName());
        String typeName = WarehouseTypeEnum.getNameById(order.getWarehouseType());
        param.put("REPORT_NAME",typeName);

        String reportName = "warehousePrint";
        StringBuffer sql = new StringBuffer();
        sql.append(" SELECT j.*,s.name as shop_name,m.name as client_name,o.name as office_name from (");
        sql.append(" SELECT ");
        sql.append("     a.id,case when a.warehouse_type in (4,5) then a.member_id else a.supplier_id end as client_id,a.shop_id,a.office_id,a.sn order_sn,b.sn,a.consignee,a.phone,a.area_name,a.address,a.order_date,b.price,b.quantity,b.price*b.quantity as amount,b.discount,a.memo ");
        sql.append(" FROM wx_warehouse a,wx_warehouse_item b");
        sql.append(" WHERE a.id = "+id+") j ");
        if (order.getWarehouseType().equals(4) || order.getWarehouseType().equals(5)) {
            sql.append(" LEFT OUTER JOIN wx_member m on j.client_id = m.id ");
        } else {
            sql.append(" LEFT OUTER JOIN wx_supplier m on j.client_id = m.id ");
        }
        sql.append(" LEFT OUTER JOIN sys_office o on j.office_id = o.id ");
        sql.append(" LEFT OUTER JOIN wx_shop s on j.shop_id = s.id ");
        sysReportService.ReportToExcelBySql(reportName, param, sql.toString(),response);
    }

    public String getName(Integer warehouseType){
        String name = "";
        WarehouseTypeEnum warehouseTypeEnum = WarehouseTypeEnum.getById(warehouseType);
        switch (warehouseTypeEnum){
            case WAREHOUSE_TYPE_SALE_IN:
                name = "warehousePrint_5";
                break;
            case WAREHOUSE_TYPE_SALE_OUT:
                name = "warehousePrint_4";
                break;
            case WAREHOUSE_TYPE_PURCHASE_IN:
                name = "warehousePrint_1";
                break;
            case WAREHOUSE_TYPE_PURCHASE_OUT:
                name = "warehousePrint_2";
                break;
            case WAREHOUSE_TYPE_ALLOCATE_IN:
                name = "warehousePrint_3";
                break;
            case WAREHOUSE_TYPE_ALLOCATE_OUT:
                name = "warehousePrint_6";
                break;
            case WAREHOUSE_TYPE_CHECK_OUT:
                name = "warehousePrint_7";
                break;
            case WAREHOUSE_TYPE_OTHER_OUT:
                name = "warehousePrint_8";
                break;
            default:
                name = "未知";
        }
        return name;
    }



    /**
     *  订单打印
     *
     * @param id
     * @return
     */
/*    @ApiOperation("打印采购单")
    @GetMapping("/printPurchase/{id}")
    public void printPurchase(HttpServletRequest request, HttpServletResponse response, @PathVariable String id)
            throws ClassNotFoundException, SQLException, JRException, IOException, IllegalAccessException{
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>打印采购单 start<<<<<<<<<<<<<<<<<<<<<<<<<<<");
        Map<String, Object> param = new HashMap<String, Object>();
        param = HttpUtils.requestParam(request);
        Enterprise enterprise = enterpriseService.getCurrent();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        param.put("COMPANY",enterprise.getName());
        param.put("enterpriseId",enterprise.getId());


        param.put("beginDate", "2020-01-01");
        param.put("endDate", "2020-01-01");


        logger.info("打印报表查询参数：{}", param.toString());


        String fileName = "purchaseCount";

        SysReport sysReport = sysReportService.selectByPrimaryKey("70fc5f481bc24c128ce3a381a161d846");

        param.put("REPORT_NAME","采购统计报表");




            sysReportService.ReportToPdfBySql(fileName, param, sysReport.getSql(), response);

    }*/

}
